package com.sinoatma.physignsmonitor.fragment

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.common.frame.base.BaseViewModel
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.formatter.ValueFormatter
import com.google.gson.Gson
import com.sinoatma.physignsmonitor.MyApp
import com.sinoatma.physignsmonitor.MyApp.Companion.monitorRecordDao
import com.sinoatma.physignsmonitor.bean.BpDataBean
import com.sinoatma.physignsmonitor.bean.ExcelColumnHead
import com.sinoatma.physignsmonitor.bean.MonitorRecordEntity
import com.sinoatma.physignsmonitor.bean.MonitorRecordsBean
import com.sinoatma.physignsmonitor.constant.BloodTransfusionModeFlag
import com.sinoatma.physignsmonitor.constant.BloodTypeModeFlag
import com.sinoatma.physignsmonitor.constant.devicesNumber
import com.sinoatma.physignsmonitor.http.NetManager
import com.sinoatma.physignsmonitor.utils.PacketTool
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.text.SimpleDateFormat
import java.util.*


class MonitorViewModel :BaseViewModel() {
    val sdfFile = SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss")

    val sdfDate = SimpleDateFormat("yyyy年MM月dd日")
    val sdfDateTime = SimpleDateFormat("HH:mm:ss")

    val sdfEarlyWarning = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
    var scanType=0

    var oxygenData: ArrayList<Entry> = ArrayList() // 血氧数据集合
    var pulseData: ArrayList<Entry> = ArrayList() //  心率数据集合

    var oxygenData2: ArrayList<Entry> = ArrayList() // 血氧数据集合
    var pulseData2: ArrayList<Entry> = ArrayList() //  心率数据集合


    var upFileFail:Int=0
    var upInfo:Int=0

    var timeStamps1: ArrayList<String> = ArrayList()
    var timeStamps2: ArrayList<String> = ArrayList()
    var bpList1 = mutableListOf<BpDataBean>()
    var bpList2 = mutableListOf<BpDataBean>()

    var bpData1=""
    var bpData2=""

    var monitorCode1:String=""
    var monitorName1:String=""
    var monitorSex1:String=""
    var monitorAge1:String=""

    var monitorCode2:String=""
    var monitorName2:String=""
    var monitorSex2:String=""
    var monitorAge2:String=""

    var filePath:String=""
    var filePathTwo:String=""

    var headList :ArrayList<ExcelColumnHead> =  ArrayList()

    var excelListData:ArrayList<MonitorRecordsBean> = ArrayList()
    var excelListDataTemp:ArrayList<MonitorRecordsBean> = ArrayList()

    var excelListDataTwo:ArrayList<MonitorRecordsBean> = ArrayList()
    var excelListDataTempTwo:ArrayList<MonitorRecordsBean> = ArrayList()


    var o2ringConnectStatus1=0
    var o2ringConnectStatus2=0


    var bPConnectStatus1=false
    var bPConnectStatus2=false



    var alertStatusRecordSpo1=""
    var alertStatusRecordPr1 =""
    var alertStatusRecordBp1 =""

    var alertStatusValueSpo1=""
    var alertStatusValuePr1 =""
    var alertStatusValueBp1 =""


    var alertStatusRecordSpo2=""
    var alertStatusRecordPr2 =""
    var alertStatusRecordBp2 =""

    var alertStatusValueSpo2=""
    var alertStatusValuePr2 =""
    var alertStatusValueBp2 =""


    var numberEarlyWarning1=0
    var numberEarlyWarning2=0

    var excelId1=""
    var excelId2=""


    var uploadInfo: MutableLiveData<String> = MutableLiveData()

    var dataMsg : MutableLiveData<String> = MutableLiveData()


    var bpTempData1=""
    var bpTempDataCount1=0

    var bpTempData2=""
    var bpTempDataCount2=0


    /**
     * 采血异常接口
     * warn     预警类型（10：血氧饱和度；20：脉搏；30：血压；40：体温）
     * status   预警状态（10：开始；0：结束）
     * reason  预警原因
     *
     */
    fun exception(lr:Int,warn1:String,warn2:String,warn3:String,
                  status:String,
                  reason1:String,reason2:String,reason3:String,
                  value1:String, value2:String, value3:String){

        var warn=""
        var reason=""
        var value=""
        if (warn1.isNotEmpty()) {
            warn=warn1
        }
        if (warn2.isNotEmpty() || warn.isNotEmpty()){
            warn="${warn}|${warn2}"
        }
        if (warn3.isNotEmpty() || warn.isNotEmpty()){
            warn="${warn}|${warn3}"
        }
        if (reason1.isNotEmpty()) {
            reason=warn1
        }
        if (reason2.isNotEmpty() || reason.isNotEmpty()){
            reason="${reason}|${reason2}"
        }
        if (reason3.isNotEmpty() || reason.isNotEmpty()){
            reason="${reason}|${reason3}"
        }
        if (value1.isNotEmpty()) {
            value=value1
        }
        if (value2.isNotEmpty() || value.isNotEmpty()){
            value="${value}|${value2}"
        }
        if (value3.isNotEmpty() || value.isNotEmpty()){
            value="${value}|${value3}"
        }




        val jsonMap = HashMap<String, String>()
        if (lr==1){
            jsonMap["donorCode"]=monitorCode1
        }else if (lr==2){
            jsonMap["donorCode"]=monitorCode2
        }
        jsonMap["warn"]=warn
        jsonMap["status"]=status
        jsonMap["reason"]=reason
        jsonMap["value"]=value
        jsonMap["time"]=sdfDateTime.format(Date())
        val gson = Gson()
        val toJson = gson.toJson(jsonMap)
        launchRequest({ NetManager.exception(RequestBody.create("application/json;charset=UTF-8".toMediaTypeOrNull(), toJson))},{
        },{
        },false)
    }



    /**
     * 文件上传接口
     */
    fun uploadFile(file: File,lr:Int){
        Log.e("zsy","${file.length()}  +${file.path}")
        val donorCodeBody: RequestBody
        if (lr==1){
            donorCodeBody = excelId1.toRequestBody("text/plain".toMediaTypeOrNull())
        }else{
            donorCodeBody = excelId2.toRequestBody("text/plain".toMediaTypeOrNull())
        }
        val requestFile: RequestBody = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
        var filePart: MultipartBody.Part= MultipartBody.Part.createFormData("file", file.name, requestFile)
        launchRequest({ NetManager.uploadFile(donorCodeBody,filePart)},{
            Log.e("zsy","上传成功")
            dataMsg.value="${lr}"
        },{
            upFileFail=lr
            Log.e("zsy","上传失败=${it.code} ${it.msg}  ${it.message}")
            dataMsg.value="上传失败=${it.code} ${it.msg}  ${it.message}"
        },showLoading = false)
    }


    /**
     * 信息上传接口
     */
    fun uploadInfo(lr:Int){
        val jsonMap = HashMap<String, String>()
        upInfo=lr
        if (lr==1){
            jsonMap["donorCode"]=monitorCode1
            jsonMap["name"]=monitorName1
            if (monitorSex1.isNotEmpty()){
                jsonMap["sex"]=if (monitorSex1=="男") "10" else "20"
            }else{
                jsonMap["sex"]="0"
            }
            jsonMap["age"]=monitorAge1
            if (BloodTransfusionModeFlag ==1){
                jsonMap["type"]=if (BloodTypeModeFlag ==0)  "10" else "20"
            }else{
                jsonMap["type"]=if (BloodTransfusionModeFlag ==1) "10" else "30"
            }
            jsonMap["status"]="10"
        }else if (lr==2){
            jsonMap["donorCode"]=monitorCode2
            jsonMap["name"]=monitorName2
            if (monitorSex2.isNotEmpty()){
                jsonMap["sex"]=if (monitorSex2=="男") "10" else "20"
            }else{
                jsonMap["sex"]="0"
            }
            jsonMap["age"]=monitorAge2
            if (BloodTransfusionModeFlag ==1){
                jsonMap["type"]= if (BloodTypeModeFlag ==0)  "10" else "20"
            }else{
                jsonMap["type"]=if (BloodTransfusionModeFlag ==1) "10" else "30"
            }
            jsonMap["status"]="10"
        }
        jsonMap["deviceNumber"]= devicesNumber
        val gson = Gson()
        val toJson = gson.toJson(jsonMap)

        Log.e("zsy","${toJson.toString()}")

        launchRequest({ NetManager.personalInfo(RequestBody.create("application/json;charset=UTF-8".toMediaTypeOrNull(), toJson))},{
            Log.e("zsy","id=${it.id}")
            if (lr==1){
                excelId1=it.id
                uploadInfo.value="信息上传成功"
            }else{
                excelId2=it.id
                uploadInfo.value="信息上传成功"
            }
        },{
            uploadInfo.value="信息上传失败  code=${it.code}   msg=${it.msg}  message=${it.message}"

        },showLoading = false)
    }

    fun  initExcelFolder(name:String,code:String){
        val dir = File(MyApp.context.getExternalFilesDir(null), "sinoatma/Excel")
        if (!dir.exists()) {
            dir.mkdirs()
        }
        filePath="${dir}/${name}-${code}-${sdfFile.format(Date())}.xlsx"
    }

    fun  initExcelFolder2(name:String,code:String){
        val dir = File(MyApp.context.getExternalFilesDir(null), "sinoatma/Excel")
        if (!dir.exists()) {
            dir.mkdirs()
        }
        filePathTwo="${dir}/${name}-${code}-${sdfFile.format(Date())}.xlsx"
    }

    fun  initHeadExcel(){
        headList.add(ExcelColumnHead("献血码",5000))
        headList.add(ExcelColumnHead("姓名",3000))
        headList.add(ExcelColumnHead("性别",2000))
        headList.add(ExcelColumnHead("年龄",2000))
        headList.add(ExcelColumnHead("血氧饱和度(%)",4000))
        headList.add(ExcelColumnHead("血压(mmHg)",4000))
        headList.add(ExcelColumnHead("脉搏(分/次)",3000))
        headList.add(ExcelColumnHead("体温(℃)",3000))
        headList.add(ExcelColumnHead("监护时间",5500))
        headList.add(ExcelColumnHead("预警时间",6500))
        headList.add(ExcelColumnHead("预警原因",8000))
        headList.add(ExcelColumnHead("数据采集设备编码",5000))
    }


    // 插入数据
    fun insertRecord(record: MonitorRecordEntity) {
        viewModelScope.launch {
            monitorRecordDao.insert(record)
        }
    }

    // 自定义电压刻度格式
    inner class OxygenFormatter : ValueFormatter() {
        override fun getFormattedValue(value: Float): String {
            return value.toInt().toString()
        }
    }

    // 自定义电流刻度格式
    inner class HeartFormatter : ValueFormatter() {
        override fun getFormattedValue(value: Float): String {
            return value.toInt().toString()  // 显示单位为"A"
        }
    }

/*        scanDecode.getBarCode(object : ScanInterface.OnScanListener {
            override fun getBarcode(data: String) {
                Log.e("zsy","${data}")
                if (viewModel.scanType==0){
                    if (data.isNotEmpty()){
                        binding.layoutMonitorInterface1.scanCodeLayout.visibility=View.GONE
                        binding.layoutMonitorInterface1.bloodDonationInfoLayout.visibility= View.VISIBLE
                        binding.layoutMonitorInterface1.scanCodeImg.setImageBitmap(data.encodeAsBitmap(750,140))
                        binding.layoutMonitorInterface1.tvScanCodeNum.text = "$data"
                    }
                }else if (viewModel.scanType==1){
                    if (data.isNotEmpty()){
                        binding.layoutMonitorInterface2.scanCodeLayout.visibility=View.GONE
                        binding.layoutMonitorInterface2.bloodDonationInfoLayout.visibility= View.VISIBLE
                        binding.layoutMonitorInterface2.scanCodeImg.setImageBitmap(data.encodeAsBitmap(600,120))
                        binding.layoutMonitorInterface2.tvScanCodeNum.text = "$data"
                    }
                }
                if (isAdded) {
                    requireActivity().sendBroadcast(Intent("com.geomobile.se4500barcodestop"))
                } else {
                    Log.e("FragmentError", "Fragment not attached to Activity")
                }

            }
            override fun getBarcodeAimid(aimid: String) {}
            override fun getBarcodeByte(bytes: ByteArray) {
            }
        })*/


    fun pulseVerification(pr:Int):String{
        return if (pr !in 60..99 ){
           "${ pr.toString()}"
        }else{
            "0"
        }
    }

    fun sopVerification(sop:Int):String{
        return if (sop in 80..93 ){
           "${ sop.toString()}"
        }else{
            "0"
        }
    }

    fun bpVerification(bp:String):String{
        val bpSplit = bp.split("/")
        if (bpSplit[1].toInt() > 89 || bpSplit[0].toInt() > 139) {
            return bp
        } else  if (bpSplit[1].toInt() < 60 || bpSplit[0].toInt() < 90){
            return bp
        }else{
            return "0"
        }
    }


    // 保存生成的数据包列表
     var lastGeneratedPacket: String = ""
    //// 原始指令数据
    var originalCommand = "A509F6000001000000"
    fun commandStartCalculate() {
        // 基于上一个数据包生成下一个
        var nextPacket=""
        if (lastGeneratedPacket.isNotEmpty()){
            nextPacket = PacketTool.generateNextPacket(lastGeneratedPacket).toString()
        }else{
            nextPacket = PacketTool.generateNextPacket(originalCommand).toString()
        }
        if (nextPacket.isNotEmpty()) {
            Log.e("zsy", "生成的下一个数据包: $nextPacket")
            // 验证CRC校验
            val isCRCValid = PacketTool.verifyCRC(nextPacket)
            Log.e("zsy", "CRC校验结果: ${if (isCRCValid) "正确" else "错误"}\n")

            // 更新上一个数据包为当前生成的数据包，供下次使用
            lastGeneratedPacket = nextPacket
        } else {
            Log.e("zsy", "生成下一个数据包失败")
        }
    }



    // 保存生成的数据包列表
    var lastGeneratedStopPacket: String = ""
    //// 原始指令数据
    var originalStopCommand = "A509F6000001000100"
    fun commandStopCalculate() {
        // 基于上一个数据包生成下一个
        var nextPacket=""
        if (lastGeneratedPacket.isNotEmpty()){
            nextPacket = PacketTool.generateNextPacket(lastGeneratedPacket).toString()
        }else{
            nextPacket = PacketTool.generateNextPacket(originalCommand).toString()
        }
        if (nextPacket.isNotEmpty()) {
            Log.e("zsy", "生成的下一个数据包: $nextPacket")
            // 验证CRC校验
            val isCRCValid = PacketTool.verifyCRC(nextPacket)
            Log.e("zsy", "CRC校验结果: ${if (isCRCValid) "正确" else "错误"}\n")

            // 更新上一个数据包为当前生成的数据包，供下次使用
            lastGeneratedPacket = nextPacket
        } else {
            Log.e("zsy", "生成下一个数据包失败")
        }
    }




}














